home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Storage / LinkSrc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  20.5 KB  |  722 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LinkSrc.cpp
  3.  
  4.     Contains:    Implementation of ODLinkSource class
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  13.  
  14.     To Do:
  15.     In Progress:
  16.         
  17. */
  18.  
  19. #define VARIABLE_MACROS
  20.  
  21. #define ODLinkSource_Class_Source
  22. #include <LinkSrc.xih>
  23.  
  24. #ifndef SOM_ODLink_xh
  25. #include <Link.xh>
  26. #endif
  27.  
  28. #ifndef _EXCEPT_
  29. #include <Except.h>
  30. #endif
  31.  
  32. #ifndef _ODMEMORY_
  33. #include <ODMemory.h>
  34. #endif
  35.  
  36. #ifndef _CONSTDEF_
  37. #include <ConstDef.h>
  38. #endif
  39.  
  40. #ifndef SOM_ODLinkManager_xh
  41. #include <LinkMgr.xh>
  42. #endif
  43.  
  44. #ifndef SOM_ODPart_xh
  45. #include <Part.xh>
  46. #endif
  47.  
  48. #ifndef SOM_ODSession_xh
  49. #include <ODSessn.xh>
  50. #endif
  51.  
  52. #ifndef SOM_ODContainer_xh
  53. #include <ODCtr.xh>
  54. #endif
  55.  
  56. #ifndef SOM_ODDocument_xh
  57. #include <Document.xh>
  58. #endif
  59.  
  60. #ifndef SOM_ODDraft_xh
  61. #include <Draft.xh>
  62. #endif
  63.  
  64. #ifndef SOM_ODStorageSystem_xh
  65. #include <ODStor.xh>
  66. #endif
  67.  
  68. #ifndef _PLFMFILE_
  69. #include <PlfmFile.h>
  70. #endif
  71.  
  72. #ifndef SOM_ODStorageUnit_xh
  73. #include <StorageU.xh>
  74. #endif
  75.  
  76. #ifndef SOM_Module_OpenDoc_StdProps_defined
  77. #include <StdProps.xh>
  78. #endif
  79.  
  80. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  81. #include <StdTypes.xh>
  82. #endif
  83.  
  84. #ifndef _ISOSTR_
  85. #include <ISOStr.h>
  86. #endif
  87.  
  88. #ifndef __ERRORS__
  89. #include <Errors.h>
  90. #endif
  91.  
  92. #ifndef _ODUTILS_
  93. #include <ODUtils.h>
  94. #endif
  95.  
  96. #ifndef _DOCUTILS_
  97. #include <DocUtils.h>
  98. #endif
  99.  
  100. #ifndef _ODDEBUG_
  101. #include <ODDebug.h>
  102. #endif
  103.  
  104. #ifndef _BARRAY_
  105. #include <BArray.h>
  106. #endif
  107.  
  108. #ifndef _STDTYPIO_
  109. #include <StdTypIO.h>
  110. #endif
  111.  
  112. #ifndef _STORUTIL_
  113. #include <StorUtil.h>
  114. #endif
  115.  
  116. #ifndef _TEMPOBJ_
  117. #include "TempObj.h"
  118. #endif
  119.  
  120. #pragma segment ODLinkSource
  121.  
  122. //==============================================================================
  123. // ODLinkSource
  124. //==============================================================================
  125.  
  126. //------------------------------------------------------------------------------
  127. // ODLinkSource: somUninit
  128. //------------------------------------------------------------------------------
  129.  
  130. SOM_Scope void  SOMLINK ODLinkSourcesomUninit(ODLinkSource *somSelf)
  131. {
  132.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  133.     ODLinkSourceMethodDebug("ODLinkSource","somUninit");
  134.  
  135.     parent_somUninit(somSelf);
  136. }
  137.  
  138. //------------------------------------------------------------------------------
  139. // ODLinkSource: InitLinkSource
  140. //------------------------------------------------------------------------------
  141.  
  142. SOM_Scope void  SOMLINK ODLinkSourceInitLinkSource(ODLinkSource *somSelf, Environment *ev,
  143.         ODStorageUnit* storageUnit,
  144.         ODPart* sourcePart)
  145. {
  146.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  147.     ODLinkSourceMethodDebug("ODLinkSource","InitLinkSource");
  148.  
  149.     SOM_TRY
  150.  
  151.     /* Moved from somInit. SOM itself sets fields to zero
  152.     _fSection = (SectionHandle) kODNULL;
  153.     _fStatus = 0;
  154.     _fDirty = kODFalse;
  155.     */
  156.     somSelf->InitBaseLinkSource(ev, storageUnit, sourcePart);
  157.  
  158.     somSelf->SetLinkSourceDirty(ev);
  159.  
  160.     SOM_CATCH_ALL
  161.     SOM_ENDTRY
  162. }
  163.  
  164. //------------------------------------------------------------------------------
  165. // ODLinkSource: InitLinkSourceFromStorage
  166. //------------------------------------------------------------------------------
  167.  
  168. SOM_Scope void  SOMLINK ODLinkSourceInitLinkSourceFromStorage(ODLinkSource *somSelf, Environment *ev,
  169.         ODStorageUnit* storageUnit)
  170. {
  171.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  172.     ODLinkSourceMethodDebug("ODLinkSource","InitLinkSourceFromStorage");
  173.  
  174.     SOM_TRY
  175.  
  176.     /* Moved from somInit. SOM itself sets fields to zero
  177.     _fSection = (SectionHandle) kODNULL;
  178.     _fStatus = 0;
  179.     _fDirty = kODFalse;
  180.     */
  181.     somSelf->InitBaseLinkSourceFromStorage(ev, storageUnit);
  182.  
  183.     if (ODSUExistsThenFocus(ev, storageUnit, kODPropLinkSection, kODApplesect) )
  184.     {
  185.         const int sectionRecordSize = sizeof(SectionRecord);
  186.  
  187.         ODValue value;
  188.  
  189.         if ( storageUnit->GetSize(ev) != sectionRecordSize )
  190.             THROW(kODErrCorruptLinkSource);
  191.  
  192.         _fSection = (SectionHandle) ODNewHandle(sectionRecordSize);
  193.         value = ODLockHandle((ODHandle) _fSection);
  194.         StorageUnitGetValue(storageUnit, ev, sectionRecordSize, value);
  195.         ODUnlockHandle((ODHandle) _fSection);
  196.         
  197.         if ( (**_fSection).kind != stSubscriber )
  198.         {
  199.             ODDisposeHandle((ODHandle) _fSection);
  200.             _fSection = (SectionHandle) kODNULL;
  201.             THROW(kODErrCorruptLinkSource);
  202.         }
  203.     
  204.         storageUnit->Focus(ev, kODPropEditionAlias, kODPosUndefined, kODApplealis, (ODValueIndex)0, kODPosUndefined);
  205.         ODULong size = storageUnit->GetSize(ev);
  206.  
  207.         if ( size < sizeof(AliasRecord) )
  208.         {
  209.             ODDisposeHandle((ODHandle) _fSection);
  210.             _fSection = (SectionHandle) kODNULL;
  211.             THROW(kODErrCorruptLinkSource);
  212.         }
  213.  
  214.         AliasHandle alias = (AliasHandle) ODNewHandle(size);
  215.         value = ODLockHandle((ODHandle) alias);
  216.         StorageUnitGetValue(storageUnit, ev, size, value);
  217.         ODUnlockHandle((ODHandle) alias);
  218.  
  219.         (**_fSection).alias = alias;
  220.         (**_fSection).refCon = (long) somSelf;
  221.  
  222.         ODDraftPermissions permissions = storageUnit->GetDraft(ev)->GetPermissions(ev);
  223.  
  224.         if (HAS_WRITE_ACCESS(permissions))
  225.         {
  226.             ODBoolean aliasWasUpdated;
  227.  
  228.             ODContainer* container = storageUnit->GetDraft(ev)->GetDocument(ev)->GetContainer(ev);
  229.             ODFileSpec documentSpec = GetODFileSpecFromContainer(ev, container);
  230.  
  231.             _fStatus = RegisterSection(&documentSpec, _fSection, &aliasWasUpdated);
  232.             
  233.             // Remember any error returned by RegisterSection.  The most likely errors are:
  234.             //    multiplePublisherWrn = -460,        A Publisher is already registered for that container
  235.             //    containerNotFoundWrn = -461,        Could not find editionContainer at this time
  236.             //    containerAlreadyOpenWrn = -462,        Container already opened by this section
  237.             //    notThePublisherWrn = -463,            Not the first registered publisher for that container
  238.  
  239.             if ( _fStatus == containerNotFoundWrn )
  240.                 _fStatus = kODErrCannotFindLinkSourceEdition;
  241.  
  242.             somSelf->Acquire(ev);    // Link must not be deleted untill its section is unregistered!
  243.         }
  244.     }
  245.  
  246.     SOM_CATCH_ALL
  247.     SOM_ENDTRY
  248. }
  249.  
  250. //------------------------------------------------------------------------------
  251. // ODLinkSource: Release (OVERRIDE)
  252. //------------------------------------------------------------------------------
  253.  
  254. SOM_Scope void  SOMLINK ODLinkSourceRelease(ODLinkSource *somSelf, Environment *ev)
  255. {
  256.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  257.     ODLinkSourceMethodDebug("ODLinkSource","Release");
  258.  
  259.     SOM_TRY
  260.  
  261.     parent_Release(somSelf, ev);
  262.  
  263. #if ODDebug
  264.     somPrintf("ODLinkSource %d::Release: Ref count is %d\n", somSelf->GetID(ev), somSelf->GetRefCount(ev));
  265. #endif
  266.  
  267.     if ( somSelf->GetRefCount(ev) == 0 )
  268.         somSelf->GetStorageUnit(ev)->GetDraft(ev)->ReleaseLinkSource(ev, somSelf);
  269.  
  270.     SOM_CATCH_ALL
  271.     SOM_ENDTRY
  272. }
  273.  
  274. //------------------------------------------------------------------------------
  275. // ODLinkSource: Externalize (OVERRIDE)
  276. //------------------------------------------------------------------------------
  277.  
  278. SOM_Scope void  SOMLINK ODLinkSourceExternalize(ODLinkSource *somSelf, Environment *ev)
  279. {
  280.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  281.     ODLinkSourceMethodDebug("ODLinkSource","Externalize");
  282.  
  283.     SOM_TRY
  284.  
  285.     parent_Externalize(somSelf,ev);
  286.  
  287.     if ( _fDirty )
  288.     {
  289.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  290.     
  291.         if ( _fSection == (SectionHandle) kODNULL )
  292.         {
  293.             ODSURemoveProperty(ev, su, kODPropLinkSection);
  294.             ODSURemoveProperty(ev, su, kODPropEditionAlias);
  295.         }
  296.         else
  297.         {
  298.             SectionPtr theSectionPtr = (SectionPtr) ODLockHandle((ODHandle) _fSection);
  299.     
  300.             ODSUForceFocus(ev, su, kODPropLinkSection, kODApplesect);
  301.             StorageUnitSetValue(su, ev, ODGetHandleSize((ODHandle) _fSection), (ODValue) theSectionPtr);
  302.             
  303.             ODValue theAliasPtr = ODLockHandle((ODHandle) theSectionPtr->alias);
  304.             ODSUForceFocus(ev, su, kODPropEditionAlias, kODApplealis);
  305.             StorageUnitSetValue(su, ev, ODGetHandleSize((ODHandle) theSectionPtr->alias), theAliasPtr);
  306.             
  307.             ODUnlockHandle((ODHandle) theSectionPtr->alias);
  308.             ODUnlockHandle((ODHandle) _fSection);
  309.         }
  310.         _fDirty = kODFalse;
  311.     }
  312.  
  313.     SOM_CATCH_ALL
  314.     SOM_ENDTRY
  315. }
  316.  
  317. //------------------------------------------------------------------------------
  318. // ODLinkSource: CloneInto (OVERRIDE)
  319. //------------------------------------------------------------------------------
  320.  
  321. SOM_Scope void  SOMLINK ODLinkSourceCloneInto(ODLinkSource *somSelf, Environment *ev,
  322.         ODDraftKey key,
  323.         ODStorageUnit* toSU,
  324.         ODFrame* scopeFrame)
  325. {
  326.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  327.     ODLinkSourceMethodDebug("ODLinkSource","CloneInto");
  328.  
  329.     SOM_TRY
  330.     
  331.     // If one of our properties already exists, this object has been cloned already
  332.     if ( toSU->Exists(ev, kODPropLinkSection, kODApplesect, 0) )
  333.         return;
  334.  
  335.     parent_CloneInto(somSelf, ev, key, toSU, scopeFrame);
  336.  
  337.     if ( _fSection != (SectionHandle) kODNULL )
  338.     {
  339.         ODSUForceFocus(ev, toSU, kODPropLinkSection, kODApplesect);
  340.         StorageUnitSetValue(toSU, ev, ODGetHandleSize((ODHandle) _fSection), (ODValue) *_fSection);
  341.         
  342.         ODSUForceFocus(ev, toSU, kODPropEditionAlias, kODApplealis);
  343.         StorageUnitSetValue(toSU, ev, ODGetHandleSize((ODHandle) (**_fSection).alias), (ODValue) *((**_fSection).alias));
  344.     }
  345.  
  346.     SOM_CATCH_ALL
  347.     SOM_ENDTRY
  348. }
  349.  
  350. //------------------------------------------------------------------------------
  351. // ODLinkSource: ReleaseAll (OVERRIDE)
  352. //------------------------------------------------------------------------------
  353.  
  354. SOM_Scope void  SOMLINK ODLinkSourceReleaseAll(ODLinkSource *somSelf, Environment *ev)
  355. {
  356.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  357.     ODLinkSourceMethodDebug("ODLinkSource","ReleaseAll");
  358.  
  359.     SOM_TRY
  360.  
  361.     parent_ReleaseAll(somSelf,ev);
  362.  
  363.     if ( _fSection != (SectionHandle) kODNULL )
  364.     {
  365.         ODDraftPermissions permissions = somSelf->GetStorageUnit(ev)->GetDraft(ev)->GetPermissions(ev);
  366.  
  367.         if (HAS_WRITE_ACCESS(permissions))
  368.         {
  369.             OSErr error = UnRegisterSection(_fSection);
  370.             somSelf->Release(ev);    // RefCount incremented when section was registered
  371.         }
  372.  
  373.         ODDisposeHandle((ODHandle) (**_fSection).alias);
  374.         ODDisposeHandle((ODHandle) _fSection);
  375.         _fSection = (SectionHandle) kODNULL;
  376.     }
  377.  
  378.     SOM_CATCH_ALL
  379.     SOM_ENDTRY
  380. }
  381.  
  382. //------------------------------------------------------------------------------
  383. // ODLinkSource: SetAutoUpdate (OVERRIDE)
  384. //------------------------------------------------------------------------------
  385.  
  386. SOM_Scope void  SOMLINK ODLinkSourceSetAutoUpdate(ODLinkSource *somSelf, Environment *ev,
  387.         ODBoolean automatic)
  388. {
  389.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  390.     ODLinkSourceMethodDebug("ODLinkSource","SetAutoUpdate");
  391.  
  392.     SOM_TRY
  393.  
  394.     parent_SetAutoUpdate(somSelf, ev, automatic);
  395.  
  396.     if ( automatic == kODFalse )
  397.     {
  398.         ODLinkManager* linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  399.         ODLink* link = kODNULL;
  400.         
  401.         TRY
  402.             link = somSelf->GetLink(ev);
  403.         CATCH_ALL
  404.         ENDTRY
  405.  
  406.         if ( link && linkManager->ExportOnSave(ev, link, kODFalse) )
  407.         {
  408.             // The link source was changed from automatic to manual updating,
  409.             // and the last change was waiting for a save to update the edition file.
  410.             // Update the edition file now, so cross-document destinations are
  411.             // consistent with destinations in the same document.  The user will not
  412.             // be able to manually update the link until another change is made
  413.             // to the source of the link.
  414.             ODLinkKey key;
  415.             if ( link->Lock(ev,0,&key) ) 
  416.             {
  417.                 TRY
  418.                     link->UpdateLinkEdition(ev, key);
  419.                 CATCH_ALL
  420.                 ENDTRY
  421.                 link->Unlock(ev, key);
  422.             }
  423.         }
  424.     }
  425.  
  426.     SOM_CATCH_ALL
  427.     SOM_ENDTRY
  428. }
  429.  
  430. //------------------------------------------------------------------------------
  431. // ODLinkSource: ShowSourceContent (OVERRIDE)
  432. //------------------------------------------------------------------------------
  433.  
  434. SOM_Scope void  SOMLINK ODLinkSourceShowSourceContent(ODLinkSource *somSelf, Environment *ev)
  435. {
  436.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  437.     ODLinkSourceMethodDebug("ODLinkSource","ShowSourceContent");
  438.  
  439.     SOM_TRY
  440.  
  441.     if ( _fSection != (SectionHandle) kODNULL )
  442.     {
  443.         EditionInfoRecord infoRec;
  444.         OSErr error;
  445.  
  446.         if ( IsRegisteredSection(_fSection) == notRegisteredSectionErr ) 
  447.         {
  448.             // Temporarily register to get Editon info
  449.             // $$$$$ This may cause an section Apple event to arrive
  450.             ODBoolean aliasWasUpdated;
  451.             ODContainer* container = somSelf->GetStorageUnit(ev)->GetDraft(ev)->GetDocument(ev)->GetContainer(ev);
  452.             ODFileSpec documentSpec = GetODFileSpecFromContainer(ev, container);
  453.             RegisterSection(&documentSpec, _fSection, &aliasWasUpdated);
  454.             error = GetEditionInfo(_fSection, &infoRec);
  455.             UnRegisterSection(_fSection);
  456.         }
  457.         else
  458.         {
  459.             error = GetEditionInfo(_fSection, &infoRec);
  460.         }
  461.         if ( error != noErr )
  462.             THROW(kODErrCannotFindLinkSource);
  463.         
  464.         error = GoToPublisherSection(&infoRec.container);
  465.         if ( error == fnfErr )
  466.             THROW(kODErrCannotFindLinkSourceEdition);
  467.         else if ( error != noErr )
  468.             THROW(kODErrCannotFindLinkSource);
  469.     }
  470.     else
  471.     {
  472.         parent_ShowSourceContent(somSelf, ev);
  473.     }
  474.     
  475.     SOM_CATCH_ALL
  476. #if ODDebug
  477.         somPrintf("ODLinkSource %d: ShowSourceContent :Error %d caught\n", somSelf->GetID(ev), ErrorCode());
  478. #endif
  479.     SOM_ENDTRY
  480. }
  481.  
  482. //------------------------------------------------------------------------------
  483. // ODLinkSource: SetSourcePart (OVERRIDE)
  484. //------------------------------------------------------------------------------
  485.  
  486. SOM_Scope void  SOMLINK ODLinkSourceSetSourcePart(ODLinkSource *somSelf, Environment *ev,
  487.         ODStorageUnit* sourcePartSU)
  488. {
  489.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  490.     ODLinkSourceMethodDebug("ODLinkSource","SetSourcePart");
  491.  
  492.     SOM_TRY
  493.  
  494.     ODLinkManager* linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  495.  
  496.     // If there is no source part for this link, delete the edition file when the
  497.     // draft is saved; is there is a source part, make sure the edition file
  498.     // is still maintained.
  499.     linkManager->DeleteOnSave(ev, somSelf->GetLink(ev), (sourcePartSU == kODNULL));
  500.  
  501.     parent_SetSourcePart(somSelf, ev, sourcePartSU);
  502.  
  503.     SOM_CATCH_ALL
  504.     SOM_ENDTRY
  505. }
  506.  
  507. //------------------------------------------------------------------------------
  508. // ODLinkSource: SetLinkSourceDirty
  509. //------------------------------------------------------------------------------
  510.  
  511. SOM_Scope void  SOMLINK ODLinkSourceSetLinkSourceDirty(ODLinkSource *somSelf, Environment *ev)
  512. {
  513.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  514.     ODLinkSourceMethodDebug("ODLinkSource","SetLinkSourceDirty");
  515.  
  516.     SOM_TRY    
  517.         _fDirty = kODTrue;
  518.  
  519.         ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  520.         if ( draft->GetPermissions(ev) != kODDPReadOnly )
  521.             draft->SetChangedFromPrev(ev);
  522.     SOM_CATCH_ALL
  523.     SOM_ENDTRY
  524. }
  525.  
  526. //------------------------------------------------------------------------------
  527. // ODLinkSource: UseLinkEdition
  528. //------------------------------------------------------------------------------
  529.  
  530. SOM_Scope void  SOMLINK ODLinkSourceUseLinkEdition(ODLinkSource *somSelf, Environment *ev,
  531.         EditionContainerSpec editionContainer,
  532.         ODFileSpec* documentSpec,
  533.         ODULong sectionID,
  534.         ODLinkKey key)
  535. {
  536.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  537.     ODLinkSourceMethodDebug("ODLinkSource","UseLinkEdition");
  538.  
  539.     SOM_TRY
  540.  
  541.     somSelf->KeyValid(ev, key);
  542.  
  543.     if ( _fSection != (SectionHandle) kODNULL )
  544.         THROW(kODErrAlreadyImportedLink);
  545.  
  546.     OSErr error = NewSection(&editionContainer, documentSpec, stSubscriber, sectionID, sumAutomatic, &_fSection);
  547.     THROW_IF_ERROR(error);
  548.  
  549.     (**_fSection).refCon = (long) somSelf;
  550.     somSelf->Acquire(ev);    // Link must not be deleted untill its section is unregistered!
  551.  
  552.     somSelf->SetLinkSourceDirty(ev);
  553.  
  554.     SOM_CATCH_ALL
  555.     SOM_ENDTRY
  556. }
  557.  
  558. //------------------------------------------------------------------------------
  559. // ODLinkSource: ReadLinkEdition
  560. //------------------------------------------------------------------------------
  561.  
  562. SOM_Scope void  SOMLINK ODLinkSourceReadLinkEdition(ODLinkSource *somSelf, Environment *ev,
  563.         ODLinkKey key)
  564. {
  565.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  566.     ODLinkSourceMethodDebug("ODLinkSource","ReadLinkEdition");
  567.  
  568.     SOM_TRY
  569.  
  570.     somSelf->KeyValid(ev, key);
  571.  
  572.     OSErr            openError;
  573.     OSErr            readError = noErr;
  574.     OSErr            closeError;
  575.     EditionRefNum    edRefNum;
  576.     ODHandle        dataHandle = kODNULL;        ODVolatile(dataHandle);
  577.     long            dataSize;
  578.     ODBoolean        successful = kODFalse;
  579.  
  580.     if ( _fSection == (SectionHandle) kODNULL )
  581.         THROW(kODErrNotImportedLink);
  582.  
  583.     openError = OpenEdition(_fSection, &edRefNum);
  584.     if ( openError )
  585.     {
  586.         _fStatus = openError;
  587.         THROW(openError);
  588.     }
  589.     else if ( _fStatus == kODErrCannotFindLinkSourceEdition )
  590.     {
  591.         _fStatus = 0;
  592.     }
  593.  
  594.     readError = EditionHasFormat(edRefNum, kODScrapTypeODBentoContainer, &dataSize);
  595.     if ( readError )
  596.         _fStatus = readError;
  597.     if ( (readError == noErr) && (dataSize > 0) )
  598.     {
  599.         TRY
  600.             dataHandle = ODNewHandle(dataSize);
  601.             void* dataPtr = ODLockHandle(dataHandle);
  602.             readError = ReadEdition (edRefNum, kODScrapTypeODBentoContainer, dataPtr, &dataSize);
  603.             ODUnlockHandle(dataHandle);
  604.             THROW_IF_ERROR(readError);
  605.  
  606.             // Changes originating in another document get a fresh change ID, since
  607.             // OpenDoc is not concerned with cycles across documents.
  608.             // Note that the source document does not mark the edition file with a change ID
  609.             // (one could be kept in the draft properties, I suppose).
  610.             ODUpdateID updateID = somSelf->GetStorageUnit(ev)->GetSession(ev)->UniqueUpdateID(ev);
  611.             somSelf->Clear(ev, updateID, key);
  612.             ODStorageUnit* contentSU = somSelf->GetContentStorageUnit(ev, key);
  613.             
  614.             // Existing properties inhibit cloning in the same property, so remove all properties
  615.             // from the content storage unit before cloning.
  616.             contentSU->Focus(ev, (ODPropertyName) kODNULL, kODPosAll, kODTypeAll, 0, kODPosUndefined);
  617.             ODULong numProperties = contentSU->CountProperties(ev);
  618.             ODULong i;
  619.             for (i = 1; i <= numProperties; i++) {
  620.                 contentSU->Focus(ev, (ODPropertyName) kODNULL, kODPosNextSib, kODTypeAll, 0, kODPosUndefined);
  621.                 contentSU->Remove(ev);
  622.                 }
  623.             
  624.             somSelf->CloneFromMemoryContainer(ev, contentSU, dataHandle);
  625.  
  626.             successful = kODTrue;
  627.  
  628.             ODDisposeHandle(dataHandle);
  629.         CATCH_ALL
  630.             _fStatus = ErrorCode();
  631.             ODDisposeHandle(dataHandle);
  632.             WARN("Throw from ReadEditionFile");
  633.         ENDTRY
  634.     }
  635.  
  636.     closeError = CloseEdition(edRefNum, successful);
  637.     if ( successful )
  638.         somSelf->SetChangeTime(ev, (**_fSection).mdDate, key);
  639.  
  640.     THROW_IF_ERROR(readError);
  641.  
  642.     SOM_CATCH_ALL
  643.     SOM_ENDTRY
  644. }
  645.  
  646. //------------------------------------------------------------------------------
  647. // ODLinkSource: SetStatus
  648. //------------------------------------------------------------------------------
  649.  
  650. SOM_Scope void  SOMLINK ODLinkSourceSetStatus(ODLinkSource *somSelf, Environment *ev,
  651.         ODError error)
  652. {
  653.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  654.     ODLinkSourceMethodDebug("ODLinkSource","SetStatus");
  655.  
  656.     _fStatus = error;
  657. }
  658.  
  659. //------------------------------------------------------------------------------
  660. // ODLinkSource: GetStatus
  661. //------------------------------------------------------------------------------
  662.  
  663. SOM_Scope ODError  SOMLINK ODLinkSourceGetStatus(ODLinkSource *somSelf, Environment *ev)
  664. {
  665.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  666.     ODLinkSourceMethodDebug("ODLinkSource","GetStatus");
  667.  
  668.     return _fStatus;
  669. }
  670.  
  671. //------------------------------------------------------------------------------
  672. // ODLinkSource: CloneFromMemoryContainer
  673. //------------------------------------------------------------------------------
  674. // This method does not call it's draft's SetChangeFromPrev() method so that the
  675. // user is not prompted to save changes if the only change was to update a link
  676. // from an edition file.
  677.  
  678.  
  679. SOM_Scope void  SOMLINK ODLinkSourceCloneFromMemoryContainer(ODLinkSource *somSelf, Environment *ev,
  680.         ODStorageUnit* contentSU,
  681.         ODHandle containerHandle)
  682. {
  683.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  684.     ODLinkSourceMethodDebug("ODLinkSource","CloneFromMemoryContainer");
  685.  
  686.     SOM_TRY
  687.  
  688.     ODStorageUnitID        rootID;
  689.     ODDraft*            myDraft = contentSU->GetDraft(ev);
  690.     ODSession*            session = somSelf->GetStorageUnit(ev)->GetSession(ev);
  691.     
  692.     TempODContainer container = GetMemoryContainer(ev, session, containerHandle, kODBentoMemoryContainer);
  693.  
  694.     TempODDocument document = container->AcquireDocument(ev, kODDefaultDocument);
  695.         
  696.     TempODDraft draft = document->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  697.         
  698.     { TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
  699.       rootID = ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
  700.     }
  701.     
  702.     TempODStorageUnit rootSU = draft->AcquireStorageUnit(ev, rootID);
  703.  
  704.     ODDraftKey draftKey = draft->BeginClone(ev, myDraft, kODNULL, kODCloneAll);
  705.     TRY
  706.         draft->Clone(ev, draftKey, rootID, contentSU->GetID(ev), 0);    
  707.  
  708.         if ( ODSUExistsThenFocus(ev, rootSU, kODPropContentFrame, kODWeakStorageUnitRef) )
  709.         {
  710.             ODID contentFrameID = ODGetWeakSURefProp(ev, rootSU, kODPropContentFrame, kODWeakStorageUnitRef);
  711.             draft->Clone(ev, draftKey, contentFrameID, kODNULLID, 0);                
  712.         }        
  713.     CATCH_ALL
  714.         draft->AbortClone(ev, draftKey);
  715.         RERAISE;
  716.     ENDTRY
  717.     draft->EndClone(ev, draftKey);
  718.  
  719.     SOM_CATCH_ALL
  720.     SOM_ENDTRY
  721. }
  722.